// 依赖收集
const targetMap = new WeakMap(); // 存放多个对象的响应式数据

let activeEffect = null; // 表示当前运行的 effect

// 注册effect
function effect(eff) {
  activeEffect = eff;
  activeEffect(); // 调用eff的时候，会触发proxy.get的逻辑， 进而在track中将eff收集到deps中
  activeEffect = null;
}

// 响应式依赖收集
function track(target, key) {
  if (activeEffect) {
    let depsMap = targetMap.get(target);
    if (!depsMap) {
      targetMap.set(target, (depsMap = new Map()));
    }
    let deps = depsMap.get(key);
    if (!deps) {
      depsMap.set(key, (deps = new Set()));
    }
    deps.add(activeEffect);
  }
}

// 触发effect更新
function trigger(target, key) {
  let depsMap = targetMap.get(target);
  if (depsMap) {
    let deps = depsMap.get(key);
    if (deps) {
      deps.forEach((effect) => effect());
    }
  }
}

// Proxy的handler
const reactiveHandler = {
  get(target, key, receiver) {
    track(target, key); // 只在effect注册的时候执行一次track收集依赖
    return Reflect.get(target, key, receiver);
  },
  set(target, key, value, receiver) {
    const oldVal = target[key];
    console.log(`oldValue:${oldVal}, value:${value}`);
    const res = Reflect.set(target, key, value, receiver); // 先赋值，再触发effect计算
    if (oldVal !== value) {
      trigger(target, key);
    }
    return Reflect.set(target, key, value, receiver);
  },
  deleteProperty(target, key) {
    return Reflect.deleteProperty(target, key);
  },
};

function reactive(obj) {
  return new Proxy(obj, reactiveHandler);
}

function ref(raw) {
  const r = {
    get value() {
      track(r, "value");
      return raw;
    },
    set value(newVal) {
      raw = newVal;
      trigger(r, "value");
    },
  };
  return r;
}

function computed(getter) {
  const r = ref();
  effect(() => {
    r.value = getter();
  });
  return r;
}
